#ifndef ALGORITHM_H
#define ALGORITHM_H

#include <unordered_map>
#include <vector>
#include <QString>  // Qt 中的 QString 类型
#include <QHash>
#include <QDebug>   // Qt 中的调试输出
#include <limits>
#include <queue>
#include <iostream>
#include <map>
#include <algorithm>
#include <fstream>
#include <QTime>
#include <QDate>
#include "resultwidget.h"
#include <memory>
#include "journeymodels.h"

const int _INFINITY_ = std::numeric_limits<int>::max();
using namespace std;


class FlightDetails {
public:
    QString airline;  // 航空公司名
    QString flightNumber;  // 航班编号
    QString deAirport;  // 起飞机场名称
    QString arrAirport;  // 降落机场名称
    QTime deTime, arrTime;  // 起飞时间和降落时间
    QDate date;  // 航班日期
    double occupancy;  // 上座率

    FlightDetails(const QString& airline, const QString& flightNumber, const QString& deAirport, const QString& arrAirport,
                  QTime deTime, QTime arrTime, QDate date, double occupancy)
        : airline(airline), flightNumber(flightNumber), deAirport(deAirport), arrAirport(arrAirport),
          deTime(deTime), arrTime(arrTime), date(date), occupancy(occupancy) {}
};


class Edge {
private:
    int m_from;
    int m_to;
    double price;
    double timeC;
    std::shared_ptr<FlightDetails> details;

public:
    Edge();
    Edge(int from, int to, double price, double timeC, std::shared_ptr<FlightDetails> details);

    int getFrom() const;
    void setFrom(int from);
    int getTo() const;
    void setTo(int to);
    double getPrice() const;
    double getTimeC() const;
    std::shared_ptr<FlightDetails> getDetails() const;
    QTime getDeTime() const;
    void setDeTime(QTime time);
    QTime getArrTime() const;
    void setArrTime(QTime time);
    QDate getDate() const;
    void setDate(QDate d);
    QString getAirline() const;
    QString getFlightNumber() const;
    QString getDepartureAirport() const;
    QString getArrivalAirport() const;
    double getOccupancy() const;
    double getWeight(int choose) const;
};

class MatrixGraph {
public:
    MatrixGraph();
    ~MatrixGraph();

    void addCity(const QString& cityName);
    void addEdge(const QString& fromCity, const QString& toCity, const QString& airline, const QString& flightNumber, const QString& deAirport,
                 const QString& arrAirport, QTime deTime, QTime arrTime, double price, double occupancy, double timeC, QDate date);

    QString Dijkstra(int choose, const QString& deCity, const QString& arrCity);
    void load(const QString& fileName);

    //QString findAllPaths(const QString& startCity, const QString& endCity, int maxTransfers);
    QList<FlightJourney> findAllPaths(const QString& startCity, const QString& endCity, int maxTransfers);
    void findAllPathsUtil(const QString& currentCity, const QString& endCity, int maxTransfers, int currentTransfers,
                          QStack<QString>& pathStack, QHash<QString, bool>& visited, QList<QString>& allPaths);
    QString constructPathDetails(const QStringList& pathList, bool hasTransfer);
    QString findAndDisplayAllPaths(const QString& startCity, const QString& endCity, int maxTransfers);

private:
    QHash<QString, int> cityIndexMap;
    std::vector<std::vector<Edge>> adjList;
    int m_vertices;
    int m_edges;
};


#endif // ALGORITHM_H
